<template>
  <transition name="fade">
    <div
      v-if="info.visible"
      ref="menuRef"
      class="liteflow-context-menu"
      :style="{ left: `${info.x}px`, top: `${info.y}px` }"
    >
      <!-- 空白场景菜单 -->
      <template v-if="info.scene === 'blank'">
        <button class="liteflow-context-menu__item" @click="handleSelectAll">全选</button>
      </template>
      <!-- 节点场景菜单 -->
      <template v-else-if="info.scene === 'node'">
        <button class="liteflow-context-menu__item" @click="handleDelete">删除</button>
      </template>
    </div>
  </transition>
</template>

<script>
import { defineComponent, computed, ref, onMounted, onBeforeUnmount } from 'vue';
import { useGraphContext } from '../composables/useGraph.js';
import { history, getModel } from '../core/index.js';

export default defineComponent({
  name: 'LiteFlowContextMenu',
  setup() {
    const { flowGraph, contextMenuInfo } = useGraphContext();
    const menuRef = ref(null);

    const info = contextMenuInfo;

    const collapseText = computed(() => {
      const graph = flowGraph.value;
      if (!graph) return '折叠/展开';
      const nodes = graph.getSelectedCells().filter((cell) => cell.isNode());
      if (!nodes.length) return '折叠/展开';
      const model = nodes[0].getData()?.model;
      if (!model) return '折叠/展开';
      return model.isCollapsed() ? '展开' : '折叠';
    });

    const handleDelete = () => {
      const graph = flowGraph.value;
      if (!graph) return;
      const nodes = graph.getSelectedCells().filter((cell) => cell.isNode());
      nodes.forEach((node) => {
        const model = node.getData()?.model;
        model?.remove?.();
      });
      history.push();
      graph.trigger('graph:hideContextMenu');
    };

    const handleCopy = () => {
      const graph = flowGraph.value;
      if (!graph) return;
      const cells = graph.getSelectedCells();
      if (cells.length > 0) {
        graph.copy(cells);
      }
      graph.trigger('graph:hideContextMenu');
    };

    const handleCollapse = () => {
      const graph = flowGraph.value;
      if (!graph) return;
      const nodes = graph.getSelectedCells().filter((cell) => cell.isNode());
      if (!nodes.length) return;
      const model = nodes[0].getData()?.model;
      if (model) {
        model.toggleCollapse();
        graph.trigger('model:change');
        history.push();
      }
      graph.trigger('graph:hideContextMenu');
    };

    const handleSelectAll = () => {
      const graph = flowGraph.value;
      if (!graph) return;
      const cells = graph.getCells();
      graph.select(cells);
      graph.trigger('graph:hideContextMenu');
    };

    const handlePaste = () => {
      const graph = flowGraph.value;
      if (!graph) return;
      if (!graph.isClipboardEmpty()) {
        graph.paste();
      }
      graph.trigger('graph:hideContextMenu');
    };

    // 点击外部关闭菜单
    const handleClickOutside = (event) => {
      if (menuRef.value && !menuRef.value.contains(event.target)) {
        const graph = flowGraph.value;
        if (graph && info.visible) {
          graph.trigger('graph:hideContextMenu');
        }
      }
    };

    onMounted(() => {
      document.addEventListener('mousedown', handleClickOutside);
    });

    onBeforeUnmount(() => {
      document.removeEventListener('mousedown', handleClickOutside);
    });

    return {
      menuRef,
      info,
      collapseText,
      handleDelete,
      handleCopy,
      handleCollapse,
      handleSelectAll,
      handlePaste,
    };
  },
});
</script>

<style lang="less" scoped>
.liteflow-context-menu {
  position: fixed;
  min-width: 140px;
  background: #fff;
  border-radius: 6px;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.15);
  padding: 8px 0;
  z-index: 1003;
  border: 1px solid rgba(15, 23, 42, 0.08);
}

.liteflow-context-menu__item {
  width: 100%;
  padding: 6px 16px;
  border: none;
  background: transparent;
  text-align: left;
  font-size: 13px;
  color: #2f3640;
  cursor: pointer;
  transition: background 0.2s ease;

  &:hover {
    background: rgba(24, 144, 255, 0.12);
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.15s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

